/*
This file is part of MMM.

MMM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

MMM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with MMM.  If not, see <http://www.gnu.org/licenses/>.
*
* @package    MMM
* @author     Nikolaus Vahrenkamp
* @copyright  2013 High Performance Humanoid Technologies (H2T), Karlsruhe, Germany
*
*/

#ifndef __MMM_ModelProcessorWinter_H_
#define __MMM_ModelProcessorWinter_H_
#include "../MMMCore.h"
#include "../MMMImportExport.h"
#include "Model.h"
#include "ModelProcessor.h"
#include "ModelProcessorFactory.h"

#include <Eigen/Core>
#include <string> 
#include <vector>
#include <map>


namespace MMM
{

/*!
	\brief Converts a 1m Winter MMM model to the requested height and weigth according to Winter's biomechanic definitions.
	The model is currently scaled according to Winter's biomechanic definitions which rely on the proband's height.
    In addition, custom segment lengths can be specified in order to apply for subject specific data.
	The class can be intiialized via an XML file. The XML property definition should look like the following example:
	\code
	 <?xml version="1.0" ?>
	   <ModelProcessorConfig type='Winter'>
	   <height>1.70</height>
	   <mass>75</mass>
       <segmentlength name='segment_name' units='mm'>100</segmentlength>
	 </ModelProcessorConfig>
	\endcode
*/
class MMM_IMPORT_EXPORT ModelProcessorWinter : public ModelProcessor
{
public:
	EIGEN_MAKE_ALIGNED_OPERATOR_NEW

	ModelProcessorWinter();

	/*!
	Convert a model
	*/
	virtual ModelPtr convertModel(ModelPtr input);

    virtual bool setup(float height, float mass, float handLength = -1., float handWidth = -1.);

    /*!
        Setup a custom segment length.
        \param segmentName The name of the segment
        \param lengthM The new length of the segemnt in meter.
        \return true on success
    */
    virtual bool setupSegmentLength(const std::string &segmentName, float lengthM);

	/*!
		Get model processor configuration as XML string.
	*/
	virtual std::string toXML(int nrTabs=0);

	float getMass();
	float getHeight();

    std::map<std::string, float> getCustomSegmentLengths();


protected:
    //! first tag in xml configuration
    virtual bool _setup(rapidxml::xml_node<char>* rootTag);

    void appendProcessorDataXML(RapidXMLWriterNodePtr processorNode);

	float height;
	float mass;
    float handLength;
    float handWidth;

    std::map<std::string, float> customSegmentLengths;
};

typedef boost::shared_ptr<ModelProcessorWinter> ModelProcessorWinterPtr;

}

#endif 
